package storage;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/*
 * 内存分配表类
 * @time:2014-10-02
 * 
 */
public class RamTable {
	
	private static List<RamData> ramDatas;//内存分配列表
	
	public RamTable(){//构造方法
		ramDatas=new LinkedList<RamData>();
	}
	
	/*
	 * 申请内存
	 * @param procId 进程id
	 * @param size	要申请的内存大小
	 * @return boolean 申请内存结果
	 * 
	 */
	public boolean apply(int procId,int size){
		
		if(size<=0){
			return false;
		}
		
		int tempStartLocation=0;	//新申请的内存首地址
		boolean sign=false;
		
		if(ramDatas.size()==0){//用户区为空时处理
			
			if(size>512){
				return false;
			}else{
				tempStartLocation=0;
				sign=true;
			}
			
		}else{//用户区不为空时处理
			
			//判断开头是否有空间
			
				
			for(RamData ramData:ramDatas){//遍历分配表
				
					if((ramData.getStartLocation()-tempStartLocation)>size){//两块内存空间之间有空余位置
						sign=true;
						break;
					}else{
						//修改指向位置
						tempStartLocation=ramData.getStartLocation()+ramData.getLength();
					}
					
				}
				
			
			
			if(!sign){//查看结尾是否有空间
				if((512-tempStartLocation)>size){//申请内存成功
					sign=true;
					
				}
			}
			
		}
		
		if(!sign){//申请空间失败
			return false;
		}
		
		RamData ramData=new RamData();
		ramData.setId(procId);
		ramData.setLength(size);
		ramData.setStartLocation(tempStartLocation);
		ramDatas.add(ramData);
		
		Collections.sort(ramDatas);//排序内存分配表
		
		return true;
		
	}
	
	
	/*
	 * 释放内存
	 * @param	procId	进程id
	 */
	public boolean free(int procId){
		
		boolean sign=false;
		int index=0;
		
		for(RamData ramData:ramDatas){//遍历内存分配表
			
			if(ramData.getId()==procId){
				sign=true;
				break;
			}
			index++;
		}
		
		if(sign){
			ramDatas.remove(index);
		}
		
		return sign;
	}
	
	public static List<RamData> getRamDatas(){
		return ramDatas;
	}
	
	public class RamData implements Comparable<RamData>{
		private int id;
		private int startLocation;
		private int length;
		
		public int getId() {
			return id;
		}
		public void setId(int id) {
			this.id = id;
		}
		public int getStartLocation() {
			return startLocation;
		}
		public void setStartLocation(int startLocation) {
			this.startLocation = startLocation;
		}
		public int getLength() {
			return length;
		}
		public void setLength(int length) {
			this.length = length;
		}
		
		@Override
		public int compareTo(RamData o) {
			
			if(this.getStartLocation()>o.getStartLocation()){
				return 1;
			}else{
				return -1;
			}
			
		}
		
		
		
	}
	
}
